﻿// BoostTCPClient.cpp: 定义应用程序的入口点。
//

#include "BoostTCPClient.h"
#include <iostream>
using namespace std;

TcpClient::TcpClient(QObject* parent) 
	: QObject(parent), socket(asio_context), timer(new QTimer(this))
{
    connect(timer, &QTimer::timeout, this, &TcpClient::SendHeartbeat);
    timer->setInterval(5000); // 设置心跳间隔为5秒
}

void TcpClient::SendHeartbeat() 
{
    std::string heartbeatMessage = "heartbeat\n";
    boost::asio::write(socket, boost::asio::buffer(heartbeatMessage));
}

void TcpClient::ConnectToServer(const QString& host, quint16 port)
{
    cout << "into ConnectToServer" << endl;
    //Resolver在Boost.Asio中用于将一个URL或者一个主机名解析成一个或一系列的Endpoint
    //Endpoint是网络编程中的一个术语，通常代表网络中的一个地址和端口
    tcp::resolver resolver(asio_context);
    tcp::resolver::results_type endpoints = resolver.resolve(host.toStdString(), std::to_string(port));
    boost::asio::connect(socket, endpoints);
    //StartReading();
    timer->start(); // 启动心跳定时器
}

void TcpClient::DisconnectFromServer()
{
    cout << "into DisconnectFromServer" << endl;
    boost::system::error_code ec;
    socket.close(ec);
    timer->stop(); // 停止心跳定时器
}

void TcpClient::StartReading()
{
    cout << "into StartReading" << endl;
    boost::asio::async_read_until(socket, receive_buf, '\n',
        [this](const boost::system::error_code& ec, std::size_t bytes_transferred) 
        {
            if (!ec) 
            {
                // 处理收到的数据
                std::istream is(&receive_buf);
                std::string message;
                std::getline(is, message);
                qDebug() << "client Received data:" << QString::fromStdString(message);

                // 处理粘包的代码
                while (is && !message.empty()) 
                {
                    qDebug() << "client Received data:" << QString::fromStdString(message);
                    std::getline(is, message);
                }

                StartReading(); // 继续读取下一条数据
            }
            else 
            {
                qDebug() << "client Read error:" << ec.message().c_str();
                DisconnectFromServer();
            }
        }
    );
}

void TcpClient::sendData(const QString& data)
{
    boost::asio::write(socket, boost::asio::buffer(data.toStdString()));
}